package jvm;

import 栈.No20有效的括号;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class MyClassLoader extends ClassLoader {

    /**
     * @param name 类的系统目录全路径,将class文件加载进jvm内存中
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) {
        byte[] bytes = null;
        try {
            InputStream is = new FileInputStream("C:\\Users\\99468\\Desktop\\IDEA_MAVEN\\the-road-of-leet-code\\target\\classes\\递归回溯\\No46全排列.class");//输入流需要借助输出流才可以转为字节数组
            int len = is.available();
            bytes = new byte[len];
            is.read(bytes);//放入此字节数组
        } catch (IOException e) {
            e.printStackTrace();
        }
        return this.defineClass(name, bytes, 0, bytes.length);//将此二进制流加载进jvm的内存中 [连接]的过程
    }

    /**
     * @param name 类信息已经在内存中了,此时需要类的全类名去查找,想要打破双亲委派,就要重写此代码
     *             不打破双亲委派就无需写此代码
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        /**
         * SPI代码的打破定义只是: 在父类加载器中使用了子类加载器帮自己做事
         * 传统来说只需要重写findClass即可
         */
        Class<?> loadedClass = super.findLoadedClass(name);//加载后就会将class缓存起来,jvm中不可重复加载
        if (loadedClass != null) {
            return loadedClass;
        }
        if (name.equals("递归回溯.No46全排列")) {
            return this.findClass(name);
        }
        //因为Class文件中有其父类Object,需要让上级加载器去找,自己找会出错,线程上下文加载器默认是应用加载器
        return Thread.currentThread().getContextClassLoader().loadClass(name);
    }

    public static void main(String[] args) throws ClassNotFoundException {
        MyClassLoader myClassLoader = new MyClassLoader();
        Class<?> aClass1 =
                myClassLoader.loadClass("栈.No20有效的括号");
        Class<?> aClass11 = //缓存中获取,为同一个class元数据
                myClassLoader.loadClass("栈.No20有效的括号");
        System.out.println(aClass1);
        No20有效的括号 no20有效的括号 = new No20有效的括号();
        System.out.println(no20有效的括号.getClass().equals(aClass1));

        MyClassLoader myClassLoader2 = new MyClassLoader();
        Class<?> aClass2 =
                myClassLoader2.loadClass("栈.No20有效的括号");
        System.out.println(aClass1.equals(aClass11));
        System.out.println(aClass2.equals(aClass1));
    }

}
